package com.example.demo.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

@Aspect   //表明此类是一个切面
@Component
public class UserAspect {

    //定义一个切点(设置拦截规则)
    @Pointcut("execution(* com.example.demo.controller.UserController.*(..))")
    public void pointcut() {
    }

    /**
     * 定义前置通知
     */
    @Before("pointcut()")
    public void doBefore() {
        System.out.println("前置通知:执行了");
    }

    /**
     *定义后置通知
     */
    @After("pointcut()")
    public void doAfter() {
        System.out.println("后置通知:执行了");
    }

    @AfterReturning("pointcut()")
    public void doAfterRuturning() {
        System.out.println("执行了: AfterReturning");
    }

    @AfterThrowing("pointcut()")
    public void doAfterThrowing() {
        System.out.println("执行了: AfterThrowing ");
    }

    /**
     * 针对pointcut切点的环绕通知
     * @param joinPoint
     * @return
     */
    @Around("pointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) {
        Object obj = null;
        //long begin = System.currentTimeMillis();
        StopWatch stopWatch = new StopWatch();
//        System.out.println("环绕通知前置方法执行了");
        try {
            stopWatch.start();
            //执行目标方法,以及一些通知
            obj = joinPoint.proceed();
            stopWatch.stop();
        } catch (Throwable e) {
            e.printStackTrace();
        }
//        System.out.println("环绕通知后置方法执行了");
        //long after = System.currentTimeMillis();
        //System.out.println("消耗了"+(after-begin)+"毫秒");
        System.out.println(joinPoint.getSignature().getName()+"方法执行花费的时间: "+stopWatch.getTotalTimeMillis()+"ms");
        return obj;
    }
}
